#include "QNode.h"

QNode::QNode()
{
	_tl = NULL;
	_tr = NULL;
	_bl = NULL;
	_br = NULL;
}

QNode::QNode(int id, CRect bound)
{
	_nodeID = id;
	_tl = NULL;
	_tr = NULL;
	_bl = NULL;
	_br = NULL;
	_bound = bound;
}

QNode::~QNode()
{
	if(_tl !=NULL)
		delete _tl;
	if(_tr !=NULL)
		delete _tr;
	if(_bl !=NULL)
		delete _bl;
	if(_bl !=NULL)
		delete _bl;
	_tl = _tr = _bl = _br = NULL;
}

void QNode::insertObjects(list<GameObject*> listObjets)
{
	_listObjects = listObjets;
}

void QNode::insertObject(GameObject* gameObject)
{
	_listObjects.push_back(gameObject);
}

int QNode::getParentID()
{
	return (int)this->_nodeID/8;
}

int QNode::getID()
{
	return _nodeID;
}

QNode* QNode::getChild(int n)
{
	switch (n)
	{
	case 1:
		return _tl;
	case 2:
		return _tr;
	case 3:
		return _bl;
	case 4:
		return _br;
	default:
		return NULL;
	}
}

void QNode::setChild(int n, QNode* p)
{
	switch(n)
	{
	case 1:
		_tl = p;
		break;
	case 2:
		_tr  = p;
		break;
	case 3:
		_bl = p;
		break;
	case 4:
		_br = p;
		break;
	}
}

// tra ve tat ca cac doi tuong trong node
// xoa nhung doi tuong co kha nang thay doi ra khoi node
// nhung doi tuong khong the thay doi thi khong xoa khoi node
list<GameObject*> QNode::getListGameObjects()
{	
	return _listObjects;

	// truong hop nay dung khi gap bug: 1 con quai di chuyen giua 2 node va bi bien mat
	list<GameObject*> result;
	list<GameObject*>::iterator it=_listObjects.begin();
	while (it!=_listObjects.end())
	{
		result.push_back(*it);
		EObjectType _type=(*it)->GetObjectType();
		switch (_type)
		{
		case EMushroom_Red:
		case EMushroom_Green:
		case EFlower:
		case EFungi:			 
		case ETurtle:			
		case EStar:
		case ELand:
			it=_listObjects.erase(it);
			//_listObjects.remove(*it);
			//it++;
			break;	
		default:
			it++;
			break;
		}
	}
	return result;
}

CRect QNode::getBound()
{
	return _bound;
}


void QNode::Insert(GameObject *gameObject)
{	
	 // check if this node intersects with gameobject
	int x = gameObject->GetPosition().x-500;
	int y = gameObject->GetPosition().y-500;
	int w = gameObject->GetBound()._width+1000;
	int h = gameObject->GetBound()._height+1000;
	CRect moveArea(x,y,w,h);
	if(this->getBound().intersectsRect(moveArea))
	// if this is node la
    if(_tr==NULL && this->getBound().intersectsRect(moveArea)==true)
	{
        this->_listObjects.push_back(gameObject);
		return;
	}
	else
	{		
		// add gameobject to child-node
		if(this->_tl->getBound().intersectsRect(moveArea))
			this->_tl->Insert(gameObject);
		if(this->_tr->getBound().intersectsRect(moveArea))
			this->_tr->Insert(gameObject);
		if(this->_bl->getBound().intersectsRect(moveArea))
			this->_bl->Insert(gameObject);
		if(this->_br->getBound().intersectsRect(moveArea))
			this->_br->Insert(gameObject);
	}  
}

void QNode::Update()
{	
	// if this is leaf node
	if(_tr==NULL)
	{
		// remove died objects
		list<GameObject*>::iterator it=_listObjects.begin();
		while( it!=_listObjects.end())
		{
			GameObject* tmp=(*it);
			if(tmp->GetObjectState()==EState::Die)
				_listObjects.erase(it++);
			else
				it++;
		}
	}
	else
	{				
		this->_tl->Update();
		this->_tr->Update();
		this->_bl->Update();
		this->_br->Update();
	}  
}

void QNode::ClearObjects()
{
	if(_listObjects.size()>0)
		_listObjects.clear();
}

list<GameObject*> QNode::GetAllObjects()
{
	return _listObjects;
}